#include "StdAfx.h"
#include "BufferIntReader.h"
#include <cstring>


bool IsOutOfBound( char* pBuff , int nLength)
{
	if( nLength == 10 )
	{
		char* pBound = "2147483647";
		for(int i = 0; i < 10; ++i )
		{
			if( pBound[i] < pBuff[i] )
			{
				return true;
			}else if( pBound[i] > pBuff[i] )
			{
				return false;
			}
		}
		return true;
	}else{
		return false;
	}
}

template< class Iter>
BufferIntReader<Iter>::BufferIntReader( Iter begin , Iter end)
{
	m_begin = begin;
	m_end = end;
	m_curr = begin;
}
template< class Iter>
BufferIntReader<Iter>::~BufferIntReader(void){}

template< class Iter>
int BufferIntReader<Iter>::GetNextInt( int* pDest )
{
	int nBufferPointer = 0;
	char cSym;
	bool bLessThanZero = false;
	while( m_curr != m_end )
	{
		cSym = (*m_curr);
		m_curr++; // move iterator and work with old value
		if(  (cSym >= '0' ) && (  cSym <= '9' ) )
		{
			m_pCharArray[ nBufferPointer ] = cSym;
		}
		else if( cSym == '-' )
		{
			if( nBufferPointer == 0 )
			{
				bLessThanZero = true;
			}else{
				return READER_RESULT_CODE_INVALID; // invalid symbol founded
			}
		}else if( (cSym == ' ') || (cSym == ',') )
		{
			// end of this number
			break;
		}else{
			return READER_RESULT_CODE_INVALID; // invalid symbol founded
		}
		// move char buffer iterator
		nBufferPointer++;
		if( nBufferPointer > 10 )
		{
			return READER_RESULT_CODE_LARGE; // Number is too large
		}
	}

	if( (m_curr == m_end) && (nBufferPointer == 0) )
		return READER_RESULT_CODE_END;
	m_pCharArray[ nBufferPointer ] = 0;
	if( IsOutOfBound( m_pCharArray , nBufferPointer ) )
		return READER_RESULT_CODE_LARGE; // number is too large

	*pDest = ReadIntFromString( m_pCharArray );
	return READER_RESULT_CODE_DONE; // readed well
}

char ArrayIterator::operator*()
{
	return m_pBuffer[ m_pointer ];
}
ArrayIterator::ArrayIterator( char* bf , long pointer , long size )
{
	m_pBuffer = bf;
	m_pointer = pointer;
	m_length = size;
}
void ArrayIterator::operator++()
{
	m_pointer++;
	if( m_pointer > m_length )
		m_pointer = m_length;
}
bool ArrayIterator::operator == (ArrayIterator const& i)
{
	return (( m_pBuffer == i.m_pBuffer) && (m_pointer == i.m_pointer ));
}
bool ArrayIterator::operator != (ArrayIterator const& i)
{
	return (( m_pBuffer != i.m_pBuffer) || (m_pointer != i.m_pointer ));
}
ArrayIterator& ArrayIterator::operator =(const ArrayIterator& other)
{
	if (this != &other)
	{
		m_pointer = other.m_pointer;
		m_pBuffer = other.m_pBuffer;
		m_length = m_length;
	}
	return *this;
}

// Convert null-terminated string to int
int ReadIntFromString( char* pBuffer )
{
	bool bMinus = false;
	int nNum = 0;
	int nPos = 0;
	if( pBuffer[0] == '-' )
	{
		bMinus = true;
		nPos++;
	}
	while( pBuffer[ nPos ] != 0 )
	{
		nNum = (nNum * 10) + ( pBuffer[ nPos ] - '0' );
		nPos++;
	}
	if( bMinus )
		nNum *= -1;

	return nNum;
}